package com.mall.controller;/*
 *
 *@author ojj
 *@date 2020/4/18 13:55
 *用户登陆注册模块
 */

import com.mall.entity.User;
import com.mall.httpResult.HttpResult;
import com.mall.httpResult.ResultCodeEnum;
import com.mall.service.UserService;
import com.mall.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/login")
public class LoginController {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    HashOperations hashOperations;
    @Autowired
    ValueOperations valueOperations;
    @Autowired
    UserService userService;
    /*
    *判断手机号是否已经被注册
    * user在redis中以hash保存，hashkey为user+phone，eg：ojj1553124654,redis中user只保存id，name
    @param[phone]
    *@return com.mall.httpResult.HttpResult
    *@author ojj
    *@date 2020/4/20 13:48
    */
    @GetMapping("/userPhone/{phone}")
    public HttpResult judgeUserExistByPhone(@PathVariable("phone") String phone){
        if(null==phone||phone.length()!=11){
            return HttpResult.failure(ResultCodeEnum.PHONE_FORMAT_ERROR);
        }
        if(redisUtil.existsKey("user"+phone)) return  HttpResult.failure(ResultCodeEnum.USER_EXIST);
        return HttpResult.success();
    }
    /*注册
    *新建user，user已在entity里注解添加参数校验
    @param[user]
    *@return com.mall.httpResult.HttpResult
    *@author ojj
    *@date 2020/4/20 15:12
    */
    @PostMapping("/user/add")
    public HttpResult newUser(@Valid @RequestBody User user){
        if(redisUtil.existsKey("user"+user.getPhone())){
            return HttpResult.failure(ResultCodeEnum.USER_EXIST);
        }
        try {//密码加密，采用MD5方式
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(user.getPassword().getBytes());
            user.setPassword(new BigInteger(1, messageDigest.digest()).toString(16));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        userService.saveUser(user);
        Map<String , String> map = new HashMap<>();
        map.put("id",String.valueOf(userService.selectIdByPhone(user.getPhone())));
        map.put("userName",user.getUsername());
        hashOperations.putAll("user"+user.getPhone() ,map);
        redisUtil.persistKey("user"+user.getPhone());
        return  HttpResult.success();
    }

    /*
    *登录
    @param[phone, password, request]
    *@return com.mall.httpResult.HttpResult
    *@author ojj
    *@date 2020/4/20 16:19
    */
    @PostMapping("/{phone}/{password}")
    public HttpResult login(@PathVariable("phone") String phone , @PathVariable("password") String password , HttpServletRequest request){
        if(!redisUtil.existsKey("user"+phone)){//用户不存在
            return HttpResult.failure(ResultCodeEnum.USER_NOT_EXIST);
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(password.getBytes());
            if(!new BigInteger(1, messageDigest.digest()).toString(16).equalsIgnoreCase(userService.findPasswordByPhone(phone))){//密码错误
                return HttpResult.failure(ResultCodeEnum.PASSWORD_ERROR);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        int userId = Integer.valueOf((String) hashOperations.get("user"+phone,"id"));
        User user = userService.getById(userId);
        if(redisUtil.existsKey("user"+userId)){//用户已登陆
            return  HttpResult.failure(ResultCodeEnum.USER_ALREADY_LOGIN,user);
        }
        //把sessionId和userId存进redis，过期时间30分钟，key：user+userId,value：sessionId
        valueOperations.set("user"+userId,request.getSession().getId(),60*30, TimeUnit.SECONDS);
        return  HttpResult.success(user);
    }

}
